"""
Case Type   : float
Case Name   : 浮点数以f/d结尾的导入导出
Create At   : 2024/10/15
Owner       : cr13
Description :
    1、修改配置文件增量检查点为on,重启数据库
    2、连接数据库，创建表，插入数据
    3、gs_dump导出(备份)内存表（目录归档格式）
    4、gs_restore导入(恢复)内存表（目录归档格式）
    5、清理环境
Expect      :
    1、修改成功，重启数据库成功
    2、连接数据库成功，创建内存表成功，插入数据成功
    3、导出数据成功
    4、导入数据成功
    5、清理环境成功
History     :
     
"""

import os
import unittest

from yat.test import macro
from yat.test import Node
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant


class MotDdlTest(unittest.TestCase):

    def setUp(self):
        self.logger = Logger()
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.user_node = Node('PrimaryDbUser')
        self.constant = Constant()
        self.commonsh = CommonSH
        self.common = Common()
        self.config = 'float_suffix_acceptance'
        self.t_name = 't_float_0022'
        self.logger.info(f'-----{os.path.basename(__file__)} start-----')
        self.logger.info('-----step1:修改配置，并重启数据库-----')
        show_msg = self.common.show_param(self.config)
        if 'on' not in show_msg:
            msg1 = self.primary_sh.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 f'{self.config}=on')
            self.logger.info(msg1)
            msg2 = self.primary_sh.restart_db_cluster()
            self.logger.info(msg2)
            msg3 = self.primary_sh.get_db_cluster_status()
            self.assertTrue("Normal" or "Degrade" in msg3)
            show_msg = self.common.show_param(self.config)
            self.assertTrue('on' in show_msg)

    def test_mot_dump(self):
        text = '-----step2:创建表，插入数据;expect:成功-----'
        self.logger.info(text)
        self.float_path = os.path.join(macro.DB_INSTANCE_PATH, 'float_test')
        sql_cmd = (f'drop table if exists t_float_0022;\n' \
                   f'create table t_float_0022(v1 float4, v2 varchar(100), v3 float8);\n' \
                   f'insert into t_float_0022 values (1.5f, \'test\', 2.5d);\n' \
                   f'insert into t_float_0022 values (-3.402E+38f, \'test\', -3.402E+38d);\n' \
                   f'insert into t_float_0022 values (3.402E+38f, \'test\', 3.402E+38d);\n' \
                   f'insert into t_float_0022 values (-3.402E+38f, \'test\', -1.79E+308d);\n' \
                   f'insert into t_float_0022 values (-3.402E+38f, \'test\', 1.79E+308d);\n' \
                   f'drop function if exists f_float_0022;' \
                   f'CREATE OR REPLACE FUNCTION f_float_0022() ' \
                   f'RETURNS TABLE(v1 float4, v2 varchar(100), v3 float4) AS \$\$'
                   f'BEGIN RETURN QUERY EXECUTE \'SELECT binary_double_infinity(v1), v2, ' \
                   f'binary_double_infinity(v3 DEFAULT 666 ON CONVERSION ERROR) ' \
                   f'FROM t_float_0022\'; END; \$\$ LANGUAGE plpgsql;')
        msg4 = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(msg4)
        self.assertEqual(msg4.count(self.constant.INSERT_SUCCESS_MSG), 5)
        self.assertEqual(msg4.count(self.constant.CREATE_FUNCTION_SUCCESS_MSG), 1)
        self.assertEqual(msg4.count(self.constant.TABLE_CREATE_SUCCESS), 1)

        text = '-----step3:gs_dump以目录归档格式导出内存表;expect:成功-----'
        self.logger.info(text)
        sql_cmd = f'''source {macro.DB_ENV_PATH};
            gs_dump {self.user_node.db_name} \
            -f {self.float_path} \
            -t {self.t_name} \
            -p {self.user_node.db_port} \
            -F c
            '''
        msg5 = self.user_node.sh(sql_cmd).result()
        self.logger.info(msg5)
        self.assertIn('dump database {} successfully'.format(
            self.user_node.db_name), msg5.splitlines()[-2].strip())

        text = '-----step4:gs_restore导入目录归档格式内存表;expect:成功-----'
        self.logger.info(text)
        sql_cmd = f'''source {macro.DB_ENV_PATH};
            gs_restore -d {self.user_node.db_name} \
            -p {self.user_node.db_port} \
            -c {self.float_path}        
            '''
        msg6 = self.user_node.sh(sql_cmd).result()
        self.logger.info(msg6)
        self.assertIn(self.constant.RESTORE_SUCCESS_MSG,
                      msg6.split('\n')[-2].strip())

        text = '-----step5:清理环境;expect:成功-----'
        self.logger.info(text)
        del_cmd = f'''source {macro.DB_ENV_PATH};
                    gsql {self.user_node.db_name} \
                    -p {self.user_node.db_port} \
                    -c "drop table {self.t_name} cascade";
                    rm -rf {self.float_path}
                    '''
        self.logger.info(del_cmd)
        del_res = self.user_node.sh(del_cmd).result()
        self.assertIn(self.constant.TABLE_DROP_SUCCESS, del_res)

    def tearDown(self):
        self.logger.info('-----this is tearDown-----')
        self.logger.info('-----恢复配置，-----')
        show_msg = self.common.show_param(self.config)
        if 'off' not in show_msg:
            msg7 = self.primary_sh.execute_gsguc('set',
                                                 self.constant.GSGUC_SUCCESS_MSG,
                                                 f'{self.config}=off')
            self.logger.info(msg7)
            msg8 = self.primary_sh.restart_db_cluster()
            self.logger.info(msg8)
            msg9 = self.primary_sh.get_db_cluster_status()
            self.assertTrue("Normal" or "Degrade" in msg9)
        msg8 = self.primary_sh.restart_db_cluster
        show_msg = self.common.show_param(self.config)
        self.assertTrue('off' in show_msg)
        self.logger.info(f'-----{os.path.basename(__file__)} end-----')


